package com.youlai.boot.system.service.impl;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.youlai.boot.system.converter.TasktableConverter;
import com.youlai.boot.system.mapper.ExportMapper;
import com.youlai.boot.system.mapper.SysUserTaskMapper;
import com.youlai.boot.system.mapper.TaskTableMapper;
import com.youlai.boot.system.model.entity.SysUserTask;
import com.youlai.boot.system.model.entity.TaskTable;
import com.youlai.boot.system.model.form.TaskTableForm;
import com.youlai.boot.system.model.query.TaskTableQuery;
import com.youlai.boot.system.model.vo.TaskTableVO;
import com.youlai.boot.system.service.TaskTableService;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.util.StrUtil;

@Service
@RequiredArgsConstructor
public class TaskTableServiceImpl extends ServiceImpl<TaskTableMapper, TaskTable> implements TaskTableService {
    private static final Logger logger = LoggerFactory.getLogger(TaskTableServiceImpl.class);
    @Autowired
    private TaskTableMapper taskTableMapper;

    private final TasktableConverter tasktableConverter;
    @Autowired
    private SysUserTaskMapper sysUserTaskMapper;
    @Autowired
    private ExportMapper exportMapper;

    private Integer cachedTaskCount;//缓存过去7天任务数量统计结果

    /**
     * 新增接口
     * @param formData@return
     * @return
     */
    @Override
    public boolean saveTasktable(TaskTableForm formData) {
        // 创建并填充TaskTable对象
        TaskTable taskTable = new TaskTable();
        taskTable.setTaskname(formData.getTaskname());
        taskTable.setArchive(formData.getArchive());
        taskTable.setId(formData.getId());

        // 尝试保存TaskTable
        boolean saved = taskTableMapper.insert(taskTable) > 0;
        if (!saved){
            return false; // 或者考虑抛出异常，取决于你的错误处理策略
        }

        // 使用保存后的任务ID和传入的doctorId创建SysUserTask对象
        SysUserTask sysUserTask = new SysUserTask();
        //sysUserTask.setUid(formData.getDoctorId()); // 直接使用传入的doctorId
        sysUserTask.setTid(taskTable.getId());

        // 返回SysUserTask插入操作的结果
        return sysUserTaskMapper.insert(sysUserTask) > 0;
    }

    /**
     * 根据医生id查询任务
     * @param doctorId
     * @return
     */
    @Override
    public List<TaskTable> getTasksByDoctorId(Long doctorId) {
        Assert.notNull(doctorId,"医生id不能为空");
        return taskTableMapper.getTaskTableByDoctorId(doctorId);
    }

    //    @Override
//    public boolean saveTasktable(TaskTableForm taskTable) {
//        TaskTable entity = tasktableConverter.toEntity(taskTable);
//        return this.save(entity);
//    }

    /**
     * 查询所有任务
     * @return
     */
    @Override
    public List<TaskTable> listAllTasks() {
        return taskTableMapper.selectList(null);
    }
    private static  final long SECONDS_PER_DAY = 86400L;//每天的秒数
    @Override
    public void addOrUpdateTask(TaskTable taskTable) {
        if (taskTable.getClosure() != null) {
            // 如果设置了实际结束时间，则计算最终耗时并设置剩余时间为0
            Duration elapsedDuration = Duration.between(taskTable.getCommencement(), taskTable.getClosure());
            double elapsedDays = elapsedDuration.getSeconds() / (double) SECONDS_PER_DAY;
            taskTable.setElapsed(elapsedDays);
            taskTable.setShengyu(0.0); // 设置剩余时间为0
        } else if (taskTable.getCommencement() != null && taskTable.getPredictcompletion() != null) {
            // 计算剩余时间和耗时
            Duration durationToCompletion = Duration.between(taskTable.getCommencement(), taskTable.getPredictstart());
            double remainingDays = Math.max(durationToCompletion.getSeconds() / (double) SECONDS_PER_DAY, 0);
            taskTable.setShengyu(remainingDays);

            if (taskTable.getCommencement() != null) {
                Duration elapsedDuration = Duration.between(taskTable.getCommencement(), LocalDateTime.now());
                double elapsedDays = elapsedDuration.getSeconds() / (double) SECONDS_PER_DAY;
                taskTable.setElapsed(elapsedDays);
            }
        }
        this.saveOrUpdate(taskTable); // 使用 MyBatis-Plus 的 saveOrUpdate 方法
    }
    @Override
    public void updateRemainingTime(Integer id) {

        try {
            TaskTable task = this.getById(id);

            if (task == null) {
                logger.warn("Task with ID {} not found.", id);
                return;
            }
            if (task.getState() == 1 || task.getClosure() != null) { // 如果任务已完成或已设置实际结束时间，则不更新剩余时间
                logger.info("Task with ID {} is already completed or has a closure time set, no need to update remaining time.", id);
                return;
            }
            if (task.getCommencement() != null && task.getPredictcompletion() != null) {
                LocalDateTime currentTime = LocalDateTime.now();
                Duration durationToCompletion = Duration.between(currentTime, task.getPredictcompletion());

                // 计算剩余时间（以天为单位）
                double remainingDays = Math.max(durationToCompletion.toDays(), 0); // 使用 toDays() 方法直接获取天数，并确保非负

                // 更新剩余时间到数据库
                task.setShengyu(remainingDays);
                // 不更新耗时字段
                // 更新数据库
                boolean updateResult = this.updateById(task);
                if (!updateResult) {
                    logger.error("Failed to update task with ID {}", id);
                } else {
                    logger.info("Successfully updated task with ID {}, remaining days: {}", id, remainingDays);
                }
            }
        } catch (Exception e) {
            logger.error("Error occurred while updating remaining time for task with ID " + id, e);
        }
    }

    /**
     * 获取首页分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage< TaskTableVO >} 首页分页列表
     */
    @Override
    public IPage<TaskTableVO> getTasktablePage(TaskTableQuery queryParams) {
        Page<TaskTableVO> pageVO = this.baseMapper.getTasktablePage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }

    /**
     * 查询所有归档任务
     *
     * @param queryParams 查询参数
     * @return {@link IPage< TaskTableVO >} 首页分页列表
     */
    @Override
    public IPage<TaskTableVO> getArchivePage(TaskTableQuery queryParams) {
        Page<TaskTableVO> pageVO = this.baseMapper.selectTasksByArchiveStatus(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }

    @Override
    public TaskTableForm getTasktableFormData(Long id) {
        TaskTable entity = this.getById(id);
        return tasktableConverter.toForm(entity);
    }

    /**
     * 单个归档
     * @param id
     * @param archive
     * @return
     */

    @Override
    public boolean updateArchive(Long id, Integer archive) {
        UpdateWrapper<TaskTable> taskTableUpdateWrapper = new UpdateWrapper<>();
        taskTableUpdateWrapper.eq("id" ,id);
        TaskTable taskTable = new TaskTable();
        taskTable.setArchive(archive);
        return taskTableMapper.update(taskTable,taskTableUpdateWrapper) > 0 ;
    }

    /**
     * 批量归档接口
     * @param id
     * @param archive
     * @return
     */
    @Override
    public boolean batchUpdateArchiveStatus(List<Long> id, Integer archive) {
        if(id == null || id.isEmpty() ) {
            return false;
        }

        UpdateWrapper<TaskTable> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id",id);

        TaskTable taskTable = new TaskTable();
        taskTable.setArchive(archive);

        return taskTableMapper.update(taskTable,updateWrapper) >0;
    }

//    /**
//     * 查询出所有已归档文件
//     * @return
//     */
//    @Override
//    public List<TaskTable> getArchiveTasks() {
//        QueryWrapper<TaskTable> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("archive",1);
//        return this.list(queryWrapper);
//    }

    /**
     * 获取任务完成情况统计数据
     * @return
     */
    @Override
    public List<Map<String, Object>> getTaskCompletionCount() {
        return taskTableMapper.getTaskCompletionCount();
    }

    /**
     * 统计过去7天内新增的任务数量
     * @return
     */
    @Override
    public Integer countTasksInLastSevenDays() {
        if (cachedTaskCount == null) {
            updateTaskCount();
        }
        return cachedTaskCount;
    }

    @Scheduled(cron = "0 0 3 * * ?")
    public void updateTaskCount() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算七天前的时间
        LocalDateTime sevenDaysAgo = now.minus(7, ChronoUnit.DAYS);

        // 构建查询条件
        QueryWrapper<TaskTable> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("addtime", sevenDaysAgo);
        queryWrapper.le("addtime", now);

        // 统计符合条件的任务数量，返回值是 Long 类型
        Long count = baseMapper.selectCount(queryWrapper);
        // 将 Long 类型转换为 Integer 类型
        cachedTaskCount = count.intValue();
    }


    @Override
    public boolean updateTasktable(Long id, TaskTableForm formData) {
        TaskTable entity = tasktableConverter.toEntity(formData);
        return this.updateById(entity);
    }
    @Override
    public boolean deleteTasktables(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的首页数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

//    @Override
//    public ResponseEntity<byte[]> exportDocument(String format) {
//        try{
//            byte[] documentBytes; // 存储生成的文档字节
//            String contentType; // 存储内容类型
//
//            // 根据格式调用相应的方法生成文档
//            if ("pdf".equalsIgnoreCase(format)) {
//                documentBytes = createPdf(); // 生成PDF文档
//                contentType = "application/pdf"; // 设置内容类型为PDF
//            } else if ("word".equalsIgnoreCase(format)) {
//                documentBytes = createWord(); // 生成Word文档
//                contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; // 设置内容类型为Word
//            } else {
//                return ResponseEntity.badRequest().body(null); // 格式不支持，返回400错误
//            }
//
//            // 设置响应头
//            HttpHeaders headers = new HttpHeaders();
//            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=document." + format); // 设置下载文件的名称
//            return new ResponseEntity<>(documentBytes, headers, HttpStatus.OK); // 返回生成的文档
//        }
//
//
//        /**
//         * 生成PDF文档
//         * @return 生成的PDF文档的字节数组
//         * @throws IOException IO异常
//         * @throws DocumentException 文档异常
//         */
//        private byte[] createPdf() throws IOException, DocumentException {
//            Document document = new Document(); // 创建PDF文档对象
//            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 创建输出流
//            PdfWriter.getInstance(document, outputStream); // 实例化PDF写入器
//            document.open(); // 打开文档
//
//            // 使用系统自带的字体
//            BaseFont baseFont = BaseFont.createFont("C:/Windows/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // 创建字体
//            Font font = new Font(baseFont); // 创建Font对象
//
//            PdfPTable table = new PdfPTable(5); // 创建5列的表格
//            table.setWidthPercentage(100); // 设置表格宽度为100%
//
//            // 添加表头
//            addHeaderCellToTable(table, "ID", font);
//            addHeaderCellToTable(table, "任务名称", font);
//            addHeaderCellToTable(table, "任务负责人", font);
//            addHeaderCellToTable(table, "任务创建时间", font);
//            addHeaderCellToTable(table, "任务优先级", font);
//            addHeaderCellToTable(table, "任务预计开始时间", font);
//            addHeaderCellToTable(table, "任务预计结束时间", font);
//            addHeaderCellToTable(table, "任务实际开始时间", font);
//            addHeaderCellToTable(table, "任务实际结束时间", font);
//            addHeaderCellToTable(table, "剩余时间", font);
//            addHeaderCellToTable(table, "耗时", font);
//            addHeaderCellToTable(table, "任务状态", font);
//
//
//            int offset = 0; // 数据偏移量
//            int batchSize = 100; // 每次获取的数据量
//            List<TaskTable> batchData; // 存储用户数据
//            int rowIndex = 1; // 行索引
//
//            do {
//                batchData = exportMapper.getDataPaging(offset, batchSize); // 分页获取用户数据
//                for (TaskTable data : batchData) {
//                    addDataRowToTable(table, data, font, rowIndex); // 添加数据行到表格
//                    rowIndex++; // 增加行索引
//                }
//                offset += batchSize; // 更新偏移量
//            } while (!batchData.isEmpty()); // 直到没有更多数据
//
//            document.add(table); // 将表格添加到文档
//            document.close(); // 关闭文档
//            return outputStream.toByteArray(); // 返回文档字节数组
//        }
//
//        /**
//         * 添加数据行到表格
//         * @param table 表格
//         * @param data 数据
//         * @param font 字体
//         * @param rowIndex 行索引
//         */
//        private void addDataRowToTable(PdfPTable table, TaskTable data, Font font, int rowIndex) {
//            boolean isGray = rowIndex % 2 != 0; // 判断当前行是否为奇数行，用于设置背景色
//            addCellToTable(table, String.valueOf(data.getId()), font, isGray);
//            addCellToTable(table, data.getUsername(), font, isGray);
//            addCellToTable(table, data.getPassword(), font, isGray);
//            addCellToTable(table, data.getPhone(), font, isGray);
//            addCellToTable(table, String.valueOf(data.getAge()), font, isGray);
//        }
//
//        /**
//         * 添加单元格到表格
//         * @param table 表格
//         * @param content 单元格内容
//         * @param font 字体
//         * @param isGray 是否为灰色背景
//         */
//        private void addCellToTable(PdfPTable table, String content, Font font, boolean isGray) {
//            PdfPCell cell = new PdfPCell(new Phrase(content, font)); // 创建单元格并设置内容和字体
//            if (isGray) {
//                cell.setBackgroundColor(BaseColor.LIGHT_GRAY); // 设置灰色背景
//            }
//            cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置单元格内容居中
//            table.addCell(cell); // 将单元格添加到表格
//        }
//
//        /**
//         * 添加表头单元格到表格
//         * @param table 表格
//         * @param content 单元格内容
//         * @param font 字体
//         */
//        private void addHeaderCellToTable(PdfPTable table, String content, Font font) {
//            PdfPCell cell = new PdfPCell(new Phrase(content, font)); // 创建表头单元格
//            cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置表头单元格内容居中
//            table.addCell(cell); // 将表头单元格添加到表格
//        }
//
//        /**
//         * 生成Word文档
//         * @return 生成的Word文档的字节数组
//         * @throws IOException IO异常
//         */
//        private byte[] createWord() throws IOException {
//            XWPFDocument document = new XWPFDocument(); // 创建Word文档对象
//            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 创建输出流
//            XWPFTable table = document.createTable(); // 创建表格
//
////        table.setWidth("100%");
//
//            // 设置表格居中
//            table.setTableAlignment(TableRowAlign.CENTER);
//
//            // 设置表格边距为0，以确保表格可以在页面中居中
//            table.setCellMargins(0, 0, 0, 0);
//
//            // 添加表头
//            XWPFTableRow headerRow = table.getRow(0); // 获取表头行
//            headerRow.getCell(0).setText("ID");
//            headerRow.createCell().setText("任务名称");
//            headerRow.createCell().setText("任务负责人");
//            headerRow.createCell().setText("任务创建时间");
//            headerRow.createCell().setText("任务优先级");
//            headerRow.createCell().setText("任务预计开始时间");
//            headerRow.createCell().setText("任务预计结束时间");
//            headerRow.createCell().setText("任务实际结束时间");
//            headerRow.createCell().setText("任务实际结束时间");
//            headerRow.createCell().setText("剩余时间");
//            headerRow.createCell().setText("耗时");
//            headerRow.createCell().setText("任务状态");
//
//
//            // 设置表头单元格的对齐方式
//            for (int i = 0; i < 5; i++) {
//                headerRow.getCell(i).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); // 设置垂直居中
//            }
//
//            int offset = 0; // 数据偏移量
//            int batchSize = 1; // 每次获取的数据量
//            List<TaskTable> batchData; // 存储用户数据
//            int rowIndex = 1; // 从 1 开始，因为第 0 行是表头
//
//            do {
//                batchData = exportMapper.getDataPaging(offset, batchSize); // 分页获取用户数据
//                for (TaskTable data : batchData) {
//                    XWPFTableRow row = table.createRow(); // 创建新行
//                    row.getCell(0).setText(String.valueOf(data.getId())); // 填充ID
//                    row.getCell(1).setText(data.getTaskname());
//                    row.getCell(2).setText(data.getTaskcharge());
//                    row.getCell(3).setText(data.getAddtime());
//                    row.getCell(4).setText(String.valueOf(data.getTaskpriority())); // 填充年龄
//
//                    // 设置背景颜色
//                    if (rowIndex % 2 != 0) { // 判断当前行是否为奇数行
//                        // 奇数行，设置背景为灰色
//                        for (int i = 0; i < 5; i++) {
//                            row.getCell(i).setColor("D9D9D9"); // 设置为浅灰色
//                        }
//                    }
//                    rowIndex++; // 增加行索引
//                }
//                offset += batchSize; // 更新偏移量
//            } while (!batchData.isEmpty()); // 直到没有更多数据
//
//            // 设置段落的对齐方式为居中
//            for (XWPFTableRow row : table.getRows()) { // 遍历所有行
//                for (XWPFTableCell cell : row.getTableCells()) { // 遍历每个单元格
//                    cell.setParagraph(cell.getParagraphs().get(0)); // 确保获取第一个段落
//                    cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); // 设置段落居中对齐
//                }
//            }
//
//            // 写入输出流
//            document.write(outputStream); // 将文档写入输出流
//            document.close(); // 关闭文档
//            return outputStream.toByteArray(); // 返回字节数组
//        }
//    }


}

